//===----------------------------------------------------------------------===//
//                         DuckDB
//
// shell_highlight.hpp
//
//
//===----------------------------------------------------------------------===//

#pragma once

#include "shell_state.hpp"

namespace duckdb_shell {

enum class PrintIntensity { STANDARD, BOLD, UNDERLINE, BOLD_UNDERLINE, ITALIC, BOLD_ITALIC };

enum class PrintColor : uint16_t;

enum class HighlightElementType : uint32_t {
	ERROR_TOKEN = 0,
	KEYWORD,
	NUMERIC_CONSTANT,
	STRING_CONSTANT,
	LINE_INDICATOR,
	DATABASE_NAME,
	SCHEMA_NAME,
	TABLE_NAME,
	COLUMN_NAME,
	COLUMN_TYPE,
	NUMERIC_VALUE,
	STRING_VALUE,
	TEMPORAL_VALUE,
	NULL_VALUE,
	FOOTER,
	LAYOUT,
	STARTUP_TEXT,
	STARTUP_VERSION,
	CONTINUATION,
	CONTINUATION_SELECTED,
	BRACKET,
	COMMENT,
	SUGGESTION_CATALOG_NAME,
	SUGGESTION_SCHEMA_NAME,
	SUGGESTION_TABLE_NAME,
	SUGGESTION_COLUMN_NAME,
	SUGGESTION_FILE_NAME,
	SUGGESTION_DIRECTORY_NAME,
	SUGGESTION_FUNCTION_NAME,
	SUGGESTION_SETTING_NAME,
	TABLE_LAYOUT,
	VIEW_LAYOUT,
	PRIMARY_KEY_COLUMN,
	PROMPT,
	NONE
};

struct HighlightColorInfo {
	const char *color_name;
	uint8_t code;
	uint8_t r;
	uint8_t g;
	uint8_t b;
};

struct HighlightElement {
	const char *name;
	PrintColor color;
	PrintIntensity intensity;
};

struct ShellHighlight {
	explicit ShellHighlight(ShellState &state);

	void PrintText(const string &text, PrintOutput output, PrintColor color, PrintIntensity intensity);
	void PrintText(const string &text, PrintOutput output, HighlightElementType type);

	void PrintError(string error_msg);

	bool SetColor(const char *element_type, const char *color, const char *intensity);
	void SetColor(HighlightElementType element_type, PrintColor print_color, PrintIntensity intensity,
	              bool user_configured = true);
	//! Whether or not a color is part of the extended color set (not available on all platforms)
	static bool IsExtendedColor(PrintColor color);
	static optional_ptr<const HighlightColorInfo> GetColorInfo(PrintColor color);
	static bool TryGetPrintColor(const char *name, PrintColor &result, string &error_msg);
	//! Gets the terminal code for a given print color (POSIX only)
	static string TerminalCode(PrintColor color, PrintIntensity intensity);
	//! Terminal code for resetting the state
	static string ResetTerminalCode();
	//! Whether or not shell highlighting is enabled
	static bool IsEnabled();
	//! Enable or disable highlighting
	static void SetHighlighting(bool enabled);

	void ToggleMode(HighlightMode mode);

	static HighlightElementType TryGetHighlightElement(const char *element_type, string &error_msg);
	static const HighlightElement &GetHighlightElement(HighlightElementType type);

public:
	ShellState &state;
};

// 8-bit print colors supported by most terminals
// the color codes 0..15 are the "classic" simple color codes supported by all terminals
// the extended color codes (16..255) are supported by most terminals on linux / macos
enum class PrintColor : uint16_t {
	STANDARD = 256,
	BLACK = 0,
	RED = 1,
	GREEN = 2,
	YELLOW = 3,
	BLUE = 4,
	MAGENTA = 5,
	CYAN = 6,
	BRIGHTGRAY = 7,
	GRAY = 8,
	BRIGHTRED = 9,
	BRIGHTGREEN = 10,
	BRIGHTYELLOW = 11,
	BRIGHTBLUE = 12,
	BRIGHTMAGENTA = 13,
	BRIGHTCYAN = 14,
	WHITE = 15,
	STANDARD_COLOR_COUNT = 16,
	GRAY0 = 16,
	NAVYBLUE = 17,
	DARKBLUE = 18,
	BLUE3 = 19,
	BLUE4 = 20,
	BLUE1 = 21,
	DARKGREEN = 22,
	DEEPSKYBLUE4 = 23,
	DEEPSKYBLUE5 = 24,
	DEEPSKYBLUE6 = 25,
	DODGERBLUE3 = 26,
	DODGERBLUE2 = 27,
	GREEN4 = 28,
	SPRINGGREEN4 = 29,
	TURQUOISE4 = 30,
	DEEPSKYBLUE3 = 31,
	DEEPSKYBLUE7 = 32,
	DODGERBLUE1 = 33,
	GREEN3 = 34,
	SPRINGGREEN3 = 35,
	DARKCYAN = 36,
	LIGHTSEAGREEN = 37,
	DEEPSKYBLUE2 = 38,
	DEEPSKYBLUE1 = 39,
	GREEN5 = 40,
	SPRINGGREEN5 = 41,
	SPRINGGREEN2 = 42,
	CYAN3 = 43,
	DARKTURQUOISE = 44,
	TURQUOISE2 = 45,
	GREEN1 = 46,
	SPRINGGREEN6 = 47,
	SPRINGGREEN1 = 48,
	MEDIUMSPRINGGREEN = 49,
	CYAN2 = 50,
	CYAN1 = 51,
	DARKRED1 = 52,
	DEEPPINK4 = 53,
	PURPLE4 = 54,
	PURPLE5 = 55,
	PURPLE3 = 56,
	BLUEVIOLET = 57,
	ORANGE4 = 58,
	GRAY37 = 59,
	MEDIUMPURPLE4 = 60,
	SLATEBLUE3 = 61,
	SLATEBLUE4 = 62,
	ROYALBLUE1 = 63,
	CHARTREUSE4 = 64,
	DARKSEAGREEN4 = 65,
	PALETURQUOISE4 = 66,
	STEELBLUE = 67,
	STEELBLUE3 = 68,
	CORNFLOWERBLUE = 69,
	CHARTREUSE3 = 70,
	DARKSEAGREEN5 = 71,
	CADETBLUE = 72,
	CADETBLUE2 = 73,
	SKYBLUE3 = 74,
	STEELBLUE1 = 75,
	CHARTREUSE5 = 76,
	PALEGREEN3 = 77,
	SEAGREEN3 = 78,
	AQUAMARINE3 = 79,
	MEDIUMTURQUOISE = 80,
	STEELBLUE2 = 81,
	CHARTREUSE2 = 82,
	SEAGREEN2 = 83,
	SEAGREEN1 = 84,
	SEAGREEN4 = 85,
	AQUAMARINE1 = 86,
	DARKSLATEGRAY2 = 87,
	DARKRED2 = 88,
	DEEPPINK5 = 89,
	DARKMAGENTA = 90,
	DARKMAGENTA2 = 91,
	DARKVIOLET1 = 92,
	PURPLE2 = 93,
	ORANGE5 = 94,
	LIGHTPINK4 = 95,
	PLUM4 = 96,
	MEDIUMPURPLE3 = 97,
	MEDIUMPURPLE5 = 98,
	SLATEBLUE1 = 99,
	YELLOW4 = 100,
	WHEAT4 = 101,
	GRAY53 = 102,
	LIGHTSLATEGRAY = 103,
	MEDIUMPURPLE = 104,
	LIGHTSLATEBLUE = 105,
	YELLOW5 = 106,
	DARKOLIVEGREEN3 = 107,
	DARKSEAGREEN = 108,
	LIGHTSKYBLUE3 = 109,
	LIGHTSKYBLUE4 = 110,
	SKYBLUE2 = 111,
	CHARTREUSE6 = 112,
	DARKOLIVEGREEN4 = 113,
	PALEGREEN4 = 114,
	DARKSEAGREEN3 = 115,
	DARKSLATEGRAY3 = 116,
	SKYBLUE1 = 117,
	CHARTREUSE1 = 118,
	LIGHTGREEN1 = 119,
	LIGHTGREEN2 = 120,
	PALEGREEN1 = 121,
	AQUAMARINE2 = 122,
	DARKSLATEGRAY1 = 123,
	RED3 = 124,
	DEEPPINK6 = 125,
	MEDIUMVIOLETRED = 126,
	MAGENTA3 = 127,
	DARKVIOLET2 = 128,
	PURPLE6 = 129,
	DARKORANGE3 = 130,
	INDIANRED1 = 131,
	HOTPINK3 = 132,
	MEDIUMORCHID3 = 133,
	MEDIUMORCHID = 134,
	MEDIUMPURPLE2 = 135,
	DARKGOLDENROD = 136,
	LIGHTSALMON3 = 137,
	ROSYBROWN = 138,
	GRAY63 = 139,
	MEDIUMPURPLE6 = 140,
	MEDIUMPURPLE1 = 141,
	GOLD3 = 142,
	DARKKHAKI = 143,
	NAVAJOWHITE3 = 144,
	GRAY69 = 145,
	LIGHTSTEELBLUE3 = 146,
	LIGHTSTEELBLUE = 147,
	YELLOW3 = 148,
	DARKOLIVEGREEN5 = 149,
	DARKSEAGREEN6 = 150,
	DARKSEAGREEN2 = 151,
	LIGHTCYAN3 = 152,
	LIGHTSKYBLUE1 = 153,
	GREENYELLOW = 154,
	DARKOLIVEGREEN2 = 155,
	PALEGREEN2 = 156,
	DARKSEAGREEN7 = 157,
	DARKSEAGREEN1 = 158,
	PALETURQUOISE1 = 159,
	RED4 = 160,
	DEEPPINK3 = 161,
	DEEPPINK7 = 162,
	MAGENTA4 = 163,
	MAGENTA5 = 164,
	MAGENTA2 = 165,
	DARKORANGE4 = 166,
	INDIANRED2 = 167,
	HOTPINK4 = 168,
	HOTPINK2 = 169,
	ORCHID = 170,
	MEDIUMORCHID1 = 171,
	ORANGE3 = 172,
	LIGHTSALMON4 = 173,
	LIGHTPINK3 = 174,
	PINK3 = 175,
	PLUM3 = 176,
	VIOLET = 177,
	GOLD4 = 178,
	LIGHTGOLDENROD3 = 179,
	TAN = 180,
	MISTYROSE3 = 181,
	THISTLE3 = 182,
	PLUM2 = 183,
	YELLOW6 = 184,
	KHAKI3 = 185,
	LIGHTGOLDENROD2 = 186,
	LIGHTYELLOW3 = 187,
	GRAY84 = 188,
	LIGHTSTEELBLUE1 = 189,
	YELLOW2 = 190,
	DARKOLIVEGREEN1 = 191,
	DARKOLIVEGREEN6 = 192,
	DARKSEAGREEN8 = 193,
	HONEYDEW2 = 194,
	LIGHTCYAN1 = 195,
	RED1 = 196,
	DEEPPINK2 = 197,
	DEEPPINK1 = 198,
	DEEPPINK8 = 199,
	MAGENTA6 = 200,
	MAGENTA1 = 201,
	ORANGERED1 = 202,
	INDIANRED3 = 203,
	INDIANRED4 = 204,
	HOTPINK = 205,
	HOTPINK5 = 206,
	MEDIUMORCHID2 = 207,
	DARKORANGE = 208,
	SALMON1 = 209,
	LIGHTCORAL = 210,
	PALEVIOLETRED1 = 211,
	ORCHID2 = 212,
	ORCHID1 = 213,
	ORANGE1 = 214,
	SANDYBROWN = 215,
	LIGHTSALMON1 = 216,
	LIGHTPINK1 = 217,
	PINK1 = 218,
	PLUM1 = 219,
	GOLD1 = 220,
	LIGHTGOLDENROD4 = 221,
	LIGHTGOLDENROD5 = 222,
	NAVAJOWHITE1 = 223,
	MISTYROSE1 = 224,
	THISTLE1 = 225,
	YELLOW1 = 226,
	LIGHTGOLDENROD1 = 227,
	KHAKI1 = 228,
	WHEAT1 = 229,
	CORNSILK1 = 230,
	GRAY100 = 231,
	GRAY3 = 232,
	GRAY7 = 233,
	GRAY11 = 234,
	GRAY15 = 235,
	GRAY19 = 236,
	GRAY23 = 237,
	GRAY27 = 238,
	GRAY30 = 239,
	GRAY35 = 240,
	GRAY39 = 241,
	GRAY42 = 242,
	GRAY46 = 243,
	GRAY50 = 244,
	GRAY54 = 245,
	GRAY58 = 246,
	GRAY62 = 247,
	GRAY66 = 248,
	GRAY70 = 249,
	GRAY74 = 250,
	GRAY78 = 251,
	GRAY82 = 252,
	GRAY85 = 253,
	GRAY89 = 254,
	GRAY93 = 255,
	EXTENDED_COLOR_COUNT = 256
};

} // namespace duckdb_shell
